package com.grf.es.highlevelrest;

import java.io.IOException;

import org.apache.lucene.queryparser.xml.builders.RangeQueryBuilder;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;

/**
 * 各种查询
 * @author 郭荣锋
 */
public class Query {

	/**
	 * 主函数
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		Query q = new Query();
		q.matchAll();
		//q.matchQuery();
		//q.termQuery();
		//q.mulMatchQuery();
		//q.boolQuery();
		//q.rangeQuery();
		//q.spanQuery();
		//q.idsQuery();
		//q.typeQuery();
		//q.fuzzyQuery();
		//q.wildcardQuery();
		//q.prefixQuery();
		//q.account();
	}
	
	/**
	 * 全匹配        match 是全文查询
	 * @throws IOException 
	 */
	public void matchAll() throws IOException {
		RestHighLevelClient client = Client.getClient();
		SearchRequest searchRequest = new SearchRequest("test"); //只能写索引名称，也就是同时查询很多张表 
		SearchResponse searchResponse = client.search(searchRequest);
		if (searchResponse.getHits().totalHits > 0) {
			System.out.println(searchResponse.toString());
		}
	}
	
	/**
	 * 匹配查询  
	 * @throws IOException 
	 */
	public void matchQuery() throws IOException {
		RestHighLevelClient client = Client.getClient();
		SearchRequest searchRequest = new SearchRequest("test");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(
				QueryBuilders.matchQuery("userName", "张三")
		);
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = client.search(searchRequest);
		System.out.println(searchResponse.toString());
	}
	
	/**
	 * 多匹配查询
	 * Text 要查询的内容
	 * fields 要查询的字段，可以有多个
	 * @throws IOException 
	 */
	public void mulMatchQuery() throws IOException {
		RestHighLevelClient client = Client.getClient();
		SearchRequest searchRequest = new SearchRequest("test");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(
				QueryBuilders.multiMatchQuery("张三", "userName")
			);
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = client.search(searchRequest);
		System.out.println(searchResponse.toString());
	}
	
	/**
	 * 单词查询   termQuery(字段， 关键字) 通过
	 * @throws IOException 
	 */
	public void termQuery() throws IOException {
		RestHighLevelClient client = Client.getClient();
		SearchRequest searchRequest = new SearchRequest("test");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(
				QueryBuilders.termQuery("userName", "李") //默认中文分词器会把中文切割成单个汉字
		);
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = client.search(searchRequest);
		System.out.println(searchResponse.toString());
	}
	
	/**
	 * 范围查询   rangeQuery()  通过 
	 * @throws IOException 
	 * 针对  时间 和  数值  的查询
	 */
	public void rangeQuery() throws IOException {
		RestHighLevelClient client = Client.getClient();
		SearchRequest searchRequest = new SearchRequest();
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//		searchSourceBuilder.query(
//				QueryBuilders.rangeQuery("userName") //字段名称
//				.from("张三") //下界
//				.to("李四") //上界
//				.includeLower(true)
//				.includeUpper(true)
//				);
		searchSourceBuilder.query(
				QueryBuilders.rangeQuery("id")
				.from(7)
				.to(8)
				.includeLower(true)
				.includeUpper(true)
				);
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = client.search(searchRequest);
		System.out.println(searchResponse.toString());
	}
	
	/**
	 * 布尔查询(与或)    复合查询
	 * @throws IOException 
	 */
	public void boolQuery() throws IOException {
		RestHighLevelClient client = Client.getClient();
		SearchRequest searchRequest = new SearchRequest("test");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(
				QueryBuilders.boolQuery().must(
						QueryBuilders.termQuery("userName", "张"))
				);
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = client.search(searchRequest);
		System.out.println(searchResponse.toString());
	}
	
	/**
	 * 范围查询 
	 * @throws IOException 
	 * spanQuery
	 */
	public void spanQuery() throws IOException {
		RestHighLevelClient client = Client.getClient();
		SearchRequest searchRequest = new SearchRequest();
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		
		//spanFirstQuery 第一个参数：要查询的字段    第二个参数：结束位置
		//此函数的作用是针对某个字段规定从第几个单词开始查到第几个结束
//		searchSourceBuilder.query(
//				QueryBuilders.spanFirstQuery(
//						QueryBuilders.spanTermQuery("userName", "张三"),2)
//				);
		//spanTermQuery  
		//此函数的作用是根据单词查询
		searchSourceBuilder.query(
				QueryBuilders.spanTermQuery("userName", "张")
				);
		//spanNearQuery 
//		searchSourceBuilder.query(
//					QueryBuilders.spanNearQuery(initialClause, slop)
//				);
//		//
//		searchSourceBuilder.query(
//				QueryBuilders.spanMultiTermQueryBuilder(multiTermQueryBuilder)
//				);
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = client.search(searchRequest);
		System.out.println(searchResponse.toString());
	}
	
	/**
	 * 前缀查询  prefixQuery()
	 * @throws IOException
	 */
	public void prefixQuery() throws IOException {
		RestHighLevelClient client = Client.getClient();
		SearchRequest searchRequest = new SearchRequest();
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(
				QueryBuilders.prefixQuery("userName", "李")
				);
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = client.search(searchRequest);
		System.out.println(searchResponse.toString());
	}
	
	/**
	 * 查询具有指定ID和类型的文档 
	 * @throws IOException 
	 */
	public void idsQuery() throws IOException {
		RestHighLevelClient client = Client.getClient();
		SearchRequest searchRequest = new SearchRequest();
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		
		searchSourceBuilder.query(
				QueryBuilders.idsQuery("user") //可以不指定类型(表)
				.addIds("1")
				);
		
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = client.search(searchRequest);
		System.out.println(searchResponse.toString());
	}
	
	/**
	 * 模糊查询   fuzzyQuery
	 * @throws IOException
	 */
	public void fuzzyQuery() throws IOException {
		RestHighLevelClient client = Client.getClient();
		SearchRequest searchRequest = new SearchRequest("test");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(
				QueryBuilders.fuzzyQuery("userName", "李")
				);
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = client.search(searchRequest);
		System.out.println(searchResponse.toString());
	}
	
	/**
	 * 根据类型查询   
	 * @throws IOException 
	 */
	public void typeQuery() throws IOException {
		RestHighLevelClient client = Client.getClient();
		SearchRequest searchRequest = new SearchRequest();
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(
				QueryBuilders.typeQuery("user")
				);
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = client.search(searchRequest);
		System.out.println(searchResponse.toString());
	}
	
	/**
	 * 通配符查询   wildcardQuery 
	 * @throws IOException 
	 */
	public void wildcardQuery() throws IOException {
		RestHighLevelClient client = Client.getClient();
		SearchRequest searchRequest = new SearchRequest("test");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(
				// ? 单字符通配    * 多字符通配,代替0个到多个字符
				QueryBuilders.wildcardQuery("userName", "*李")
				);
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = client.search(searchRequest);
		System.out.println(searchResponse.toString());
	}
	
	/**
	 * 统计
	 * @throws IOException 
	 */
	public void account() throws IOException {
		RestHighLevelClient client = Client.getClient();
		AggregationBuilder aggregationBuilder = AggregationBuilders.count("总数").field("id");
		SearchRequest searchRequest = new SearchRequest("test");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().size(10);
		searchSourceBuilder.aggregation(aggregationBuilder);
		searchSourceBuilder.query(
				QueryBuilders.matchAllQuery()
				);
		
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = client.search(searchRequest);
		System.out.println(searchResponse.toString());
	}
	
}
